package com.sourcespro.db;

import com.sourcespro.Env;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yaml.snakeyaml.Yaml;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * genCode
 *
 * @author zhanghaowei
 * @date 2018/6/15
 */
public class DBUtils {

    private static final Logger logger = LoggerFactory.getLogger(DBUtils.class);

    public static List<DBColumn> getColumnList(String table){
        List<DBColumn> result = new ArrayList<>();
        Connection connection = getConnection();
        if (connection == null) {
            return result;
        }
        try {
            String catalog = connection.getCatalog();
            String schemaPattern = connection.getMetaData().getUserName();
            DatabaseMetaData metaData = connection.getMetaData();
            ResultSet rs = metaData.getColumns(catalog, schemaPattern, table, "%");
            while (rs.next()){
                DBColumn dbColumn = new DBColumn();
                dbColumn.setName(rs.getString("COLUMN_NAME"));
                String typeName = rs.getString("TYPE_NAME");
                if (typeName.equalsIgnoreCase("int unsigned")){
                    dbColumn.setType("INTEGER");
                } else {
                    dbColumn.setType(typeName);
                }
                dbColumn.setNote(rs.getString("REMARKS"));
                result.add(dbColumn);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return result;
    }

    public static Connection getConnection(){
        DBConInfo dbConInfo = getDBConInfo();
        Connection connection = null;
        try {
            Class.forName(dbConInfo.getDriverClassName());
            connection = DriverManager.getConnection(dbConInfo.getUrl(), dbConInfo.getUsername(), dbConInfo.getPassword());
        } catch (ClassNotFoundException | SQLException e) {
            logger.error("jdbc connect error. \n {}", e);
        }
        return connection;
    }

    private static DBConInfo getDBConInfo(){
        //获取spring boot项目application.yml中配置的数据库信息
        Yaml yaml = new Yaml();
        String applicationPath = Env.resourcesPath + "application.yml";
        logger.info("load conf from {}", applicationPath);
        Map appConfMap = null;
        try {
            appConfMap = yaml.loadAs(new FileInputStream(new File(applicationPath)), HashMap.class);
        } catch (FileNotFoundException e) {
            logger.error("读取配置文件失败：path={} \n {}", applicationPath, e);
        }

        Map spring = (Map) appConfMap.get("spring");
        Map profiles = (Map) spring.get("profiles");
        String active = (String) profiles.get("active");
        if (active != null) {
            applicationPath = applicationPath.replace("application", "application-" + active);
            logger.info("load db conf from {}", applicationPath);
            Map appDbConfig = null;
            try {
                appDbConfig = yaml.loadAs(new FileInputStream(new File(applicationPath)), HashMap.class);
            } catch (FileNotFoundException e) {
                logger.error("读取配置文件失败：path={} \n {}", applicationPath, e);
                throw new RuntimeException("读取配置文件失败");
            }
            return parseConf(appDbConfig);
        }
        return parseConf(appConfMap);
    }

    private static DBConInfo parseConf(Map appDbConfig) {
        DBConInfo conInfo = new DBConInfo();
        Map springDB = (Map) appDbConfig.get("spring");
        Map datasource = (Map) springDB.get("datasource");
        Map druid = (Map) datasource.get("druid");
        String url;
        String username;
        String password;
        String driverClassName;
        if (druid == null) {
            url = (String) datasource.get("url");
            username = (String) datasource.get("username");
            password = String.valueOf(datasource.get("password"));
            driverClassName = (String) datasource.get("driver-class-name");
        } else {
            url = (String) druid.get("url");
            username = (String) druid.get("username");
            password = String.valueOf(druid.get("password"));
            driverClassName = (String) druid.get("driver-class-name");
        }
        conInfo.setUrl(url);
        conInfo.setUsername(username);
        conInfo.setPassword(password);
        conInfo.setDriverClassName(driverClassName.replace("cj.", ""));
        //logger.info("\n url={} \n username={} \n password={} \n driverClassName={}", url, username, password, driverClassName);
        return conInfo;
    }

}
